
///
/// https://www.codewars.com/kata/5886e082a836a691340000c3/rust
/// 从题中可知，矩形必然存在一个中心点，即坐标原点O
/// 1. 根据矩形的宽高，算出中心点到边长可以存在几个点
/// 2. 算出宽度方向上共有几列， 列数乘上行数算出大致多少个点
/// 3. 然后再加上漏算的点
/// 
fn rectangle_rotation(a: i32, b: i32) -> i32 {
    let degree = 45;
    let point_des = 1.0_f64 / (2.0_f64).sqrt();
    println!("point_des: {}", point_des);
    let half_h = (a as f64 / 2.0_f64 / point_des).floor() as i32;
    let half_w = (b as f64 / 2.0_f64 / point_des).floor() as i32;
    let h = half_h * 2 + 1;
    let w = half_w * 2 + 1;
    println!("h: {}, w: {}", h, w);
    let more = if half_h % 2 == 0 { 
        ((half_w as f64 / 2.0f64).floor() as i32 * 2) + 1
    } else {
        ((half_w as f64 / 2.0f64).ceil() as i32 * 2)
    };
    // 将图顺时针旋转45度，将点的列数乘上行数，会少算一些， 需要加上，
    (w * half_h) + more
}

///
/// 这个是codewars上最简洁(截至2021-04-08)的答案
/// 
fn rectangle_rotation_1(a: i32, b: i32) -> i32 {
    // 算出a方向上可以放多少个点
    let u = (a as f64 / std::f64::consts::SQRT_2) as i32;
    // 算出b方向上可以放多少个点
    let v = (b as f64 / std::f64::consts::SQRT_2) as i32;
    (u + 1) * (v + 1) // 算出和原点相差N倍对角距离的点数
    + u * v  // 算出和原点相差N倍半对角距离的点数
    - (u + v) % 2 
}

fn rectangle_rotation_2(a: i32, b: i32) -> i32 {
    use std::f32::consts::SQRT_2;
    let x = (a as f32 / SQRT_2) as i32;
    let y = (b as f32 / SQRT_2) as i32;
    if x % 2 == y % 2 {
        x * y + (x + 1) * (y + 1)
    } else {
        x * (y + 1) + y * (x + 1)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn basic_tests() {
        assert_eq!(rectangle_rotation(6, 4), 23);
        assert_eq!(rectangle_rotation(30, 2), 65);
        assert_eq!(rectangle_rotation(8, 6), 49);
        assert_eq!(rectangle_rotation(16, 20), 333);
    }
}